package cn.lijiajia3515.starter.web.autoconfigure;

import cn.lijiajia3515.cairo.web.servlet.method.BusinessResultBodyAdvice;
import cn.lijiajia3515.cairo.web.servlet.method.RequestMessageParamMethodProcessor;
import cn.lijiajia3515.starter.web.jackson.CairoJacksonProperties;
import cn.lijiajia3515.starter.web.jackson.StandardJackson2ObjectMapperBuilderCustomizer;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;

import java.util.Arrays;
import java.util.List;

@Configuration(proxyBeanMethods = false)
@AutoConfigureAfter(value = {WebMvcAutoConfiguration.EnableWebMvcConfiguration.class, SpringWebAutoConfiguration.class})
public class CairoWebAutoConfiguration {

	@Bean
	public BusinessResultBodyAdvice businessResultBodyAdvice() {
		return new BusinessResultBodyAdvice();
	}

//	@Bean
//	@ConditionalOnClass(value = {BusinessResultBodyMethodHandler.class})
//	@ConditionalOnMissingBean
//	public BusinessResultBodyMethodHandler businessResultBodyMethodHandler(List<HttpMessageConverter<?>> converters, List<ResponseBodyAdvice<?>> responseBodyAdvices) {
//		return new BusinessResultBodyMethodHandler(converters, responseBodyAdvices);
//	}


	@Bean
	@ConditionalOnMissingBean
	public RequestMessageParamMethodProcessor requestMessageParamMethodProcessor(List<HttpMessageConverter<?>> converters) {
		return new RequestMessageParamMethodProcessor(converters);
	}


	@Bean
	@ConfigurationProperties("cairo.jackson.v1")
	public CairoJacksonProperties cairoV1JacksonProperties() {
		return new CairoJacksonProperties();
	}

	ObjectMapper cairoV1ObjectMapper(ApplicationContext applicationContext,
									 @Qualifier("cairoV1JacksonProperties") CairoJacksonProperties properties) {

		Jackson2ObjectMapperBuilderCustomizer customizer = new StandardJackson2ObjectMapperBuilderCustomizer(applicationContext, properties);
		Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
		customizer.customize(builder);

		return builder.createXmlMapper(false).build();
	}

	@Bean
	@Order(200)
	MappingJackson2HttpMessageConverter cairoV1HttpMessageConverter(ApplicationContext applicationContext,CairoJacksonProperties properties) {
		MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(cairoV1ObjectMapper(applicationContext,properties));
		converter.setSupportedMediaTypes(Arrays.asList(
			new MediaType("application", "vnd.cairo.v1+json"),
			new MediaType("application", "vnd.cairo.*+json")
		));
		return converter;
	}


}
